﻿using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using Service.Helpers;
using Service.Model;
using Service.Model.Context;
using Service.Workflow.Game.Command;
using Service.Workflow.GamePlayer.Command;
using Service.Workflow.LearningWeight.Command;
using Service.Workflow.Opening.Query;
using Service.Workflow.Player.Command;
using Service.Workflow.PlayerHeuristic.Command;
using ShortBus;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Service.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(Service.App_Start.NinjectWebCommon), "Stop")]
namespace Service.App_Start
{
    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper Bootstrapper = new Bootstrapper();
        private static IKernel _kernel;

        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            Bootstrapper.Initialize(CreateKernel);
            
        }

        public static void Stop()
        {
            Bootstrapper.ShutDown();
        }

        public static IKernel GetKernel()
        {
            return _kernel;
        }
        
        private static IKernel CreateKernel()
        {
            _kernel = new StandardKernel();
            try
            {
                _kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                _kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                //GlobalConfiguration.Configuration.DependencyResolver = new Ninject.Web.WebApi.NinjectDependencyResolver(kernel);

                _kernel.Bind<IDependencyResolver>()
                      .To<ShortBus.Ninject.NinjectDependencyResolver>()
                      .InSingletonScope();

                RegisterServices();
                return _kernel;
            }
            catch
            {
                _kernel.Dispose();
                throw;
            }
        }

        private static void RegisterServices()
        {
            _kernel.Bind<IMediator>().To<Mediator>().InSingletonScope();

            _kernel.Bind<ServiceDbContext>().ToSelf().InSingletonScope();

            _kernel.Bind<IGameHelper>().To<GameHelper>().InSingletonScope();

            _kernel.Bind<IAsyncQueryHandler<CreateGameCommand, CreateGameCommandResponse>>().To<CreateGameCommandHandler>().InSingletonScope();
            _kernel.Bind<IAsyncQueryHandler<CreatePlayerCommand, CreatePlayerCommandResponse>>().To<CreatePlayerCommandHandler>().InSingletonScope();
            _kernel.Bind<IAsyncQueryHandler<CreatePlayerHeuristicsCommand, CreatePlayerHeuristicsCommandResponse>>().To<CreatePlayerHeuristicsCommandHandler>().InSingletonScope();
            _kernel.Bind<IAsyncQueryHandler<CreateGamePlayerCommand, CreateGamePlayerCommandResponse>>().To<CreateGamePlayerCommandHandler>().InSingletonScope();
            _kernel.Bind<IAsyncQueryHandler<MoveGameCommand, MoveGameCommandResponse>>().To<MoveGameCommandHandler>().InSingletonScope();

            _kernel.Bind<IAsyncQueryHandler<OpeningQuery, OpeningQueryResponse>>().To<OpeningQueryHandler>().InSingletonScope();
            
            _kernel.Bind<IAsyncQueryHandler<LearnWeightCommand, LearnWeightCommandResponse>>().To<LearnWeightCommandHandler>().InSingletonScope();
        }
    }
}
